#!/usr/bin/python
##############################################################################
# $Header: $
##############################################################################
# Distributed under the terms of the GNU General Public License, v2 or later
# Author: Ned Ludd <solar@gentoo.org> (glue all the parts together)
# Author: Eldad Zack <eldad@gentoo.org> (earch)
# Author : Eric Olinger <EvvL AT RustedHalo DOT net> (metadata)

# Gentoo metadata xml and arch keyword checking tool.

import os,sys,portage
import string,re
from stat import *
from output import *
from xml.sax import saxutils, make_parser, handler
from xml.sax.handler import feature_namespaces

#sys.path.insert(0, "/usr/lib/portage/pym")

version="0.4.1"

def getvar(pkg, var):
	file = open(pkg + ".ebuild")
	for line in file.readlines():
		line = string.rstrip(line)
		if re.match("^"+var+"=",line):
			vars = re.split("\"",line)[1]
			file.close
			return re.split(" ",vars)
	file.close

def earch(workdir):
	"""Prints arch keywords for a given dir"""
	portdir = portage.settings["PORTDIR"]
	#workdir = "."
	os.chdir(workdir)

	archdict = {}
	ebuildlist = []
	for file in os.listdir(workdir):
		if re.search("\.ebuild$",file):
			ebuildlist.append(re.split("\.ebuild$",file)[0])

	ebuildlist.sort(lambda x,y: portage.pkgcmp(portage.pkgsplit(x),portage.pkgsplit(y)))

	for pkg in ebuildlist:
		keywords = getvar(pkg, "KEYWORDS")
		for arch in keywords:
			archdict[arch] = pkg

	for pkg in ebuildlist:
		print darkgreen("Keywords: ") + pkg + ": ",
		for value,key in archdict.iteritems():
			if (key == pkg):
				if value[0] == "-":
					print red(value),
				elif "~" == value[0]:
					print blue(value),				
				else:
					print green(value),
		print ""


class Metadata_XML(handler.ContentHandler):
	_inside_herd="No"
	_inside_maintainer="No"
	_inside_email="No"
	_inside_longdescription="No"

	_herd = ""
	_maintainers = []
	_longdescription = ""

	def startElement(self, tag, attr):
		if tag == "herd":
			self._inside_herd="Yes"
		if tag == "longdescription":
			self._inside_longdescription="Yes"
		if tag == "maintainer":
			self._inside_maintainer="Yes"
		if tag == "email":
			self._inside_email="Yes"

	def endElement(self, tag):
		if tag == "herd":
			self._inside_herd="No"
		if tag == "longdescription":
			self._inside_longdescription="No"
		if tag == "maintainer":
			self._inside_maintainer="No"
		if tag == "email":
			self._inside_email="No"

	def characters(self, contents):
		if self._inside_herd == "Yes":
			self._herd = contents

		if self._inside_longdescription == "Yes":
			self._longdescription = contents
			
		if self._inside_maintainer=="Yes" and self._inside_email=="Yes":
			self._maintainers.append(contents)


def check_metadata(full_package):
	"""Checks that the primary maintainer is still an active dev and list the hed the package belongs to"""
	metadata_file=portage.settings["PORTDIR"] + "/" + portage.pkgsplit(full_package)[0] + "/metadata.xml"
	if not os.path.exists(metadata_file):
		print darkgreen("Maintainer: ") + red("Error (Missing metadata.xml)")
		return 1

	parser = make_parser()
	handler = Metadata_XML()
	handler._maintainers = []
	parser.setContentHandler(handler)
	parser.parse( metadata_file )

	if len(handler._herd) < 1:
		print darkgreen("Herd: ") + red("Error (No Herd)")
		return 1
	else:
		print darkgreen("Herd: ") + handler._herd

	if len(handler._maintainers) < 1:
		print darkgreen("Maintainer: ") + handler._herd
	else:
		print darkgreen("Maintainer: ") + ", ".join(handler._maintainers)

	if len(handler._longdescription) > 1:
		print darkgreen("Description: ") + handler._longdescription
	print darkgreen("Location: ") + os.path.normpath(portage.settings["PORTDIR"] + "/" + portage.pkgsplit(full_package)[0])


def usage(code):
	"""Prints the uage information for this script"""
	print green("epkginfo v" + version + "\n")
	print "Usage: epkginfo [package-cat/]package"
	sys.exit(code)


# default color setup
if ( not sys.stdout.isatty() ) or ( portage.settings["NOCOLOR"] in ["yes","true"] ):
	nocolor()

def fc(x,y):
	return cmp(y[0], x[0])


def grab_changelog_devs(catpkg):
	try:
		os.chdir(portage.settings["PORTDIR"] + "/" + catpkg)
		foo=""
		r=re.compile("<[^@]+@gentoo.org>", re.I)
		s="\n".join(portage.grabfile("ChangeLog"))
		d={}
		for x in r.findall(s):
			if x not in d:
				d[x] = 0
			d[x] += 1

		l=[(d[x], x) for x in d.keys()]
		#l.sort(lambda x,y: cmp(y[0], x[0]))
		l.sort(fc)
		for x in l:
			p = str(x[0]) +" "+ x[1].lstrip("<").rstrip(">")
			foo += p[:p.find("@")]+", "
		return foo
	except:
		raise

def main ():
	if len( sys.argv ) < 2:
		usage(1)

	for pkg in sys.argv[1:]:

		if sys.argv[1:][:1] == "-":
			print "NOT WORKING?=="+sys.argv[1:]
			continue

		try:
			package_list = portage.portdb.xmatch("match-all", pkg)
			if package_list:

				catpkg = portage.pkgsplit(package_list[0])[0]

				print darkgreen("Package: ") + catpkg
				check_metadata(package_list[0])
				earch(portage.settings["PORTDIR"] + "/" + catpkg)
				print darkgreen("ChangeLog: ") + grab_changelog_devs(catpkg)
				print ""
		except:
			print red("Error: "+pkg+"\n")


if __name__ == '__main__':
	main()
